/** 
 * <p>Original Author:  jessefreeman</p>
 * <p>Based off of a post by Manish Jethani at 
 * http://manishjethani.com/guaranteeing-enumeration-order</p>
 * 
 * <p>Class File: OffsetProperties.as</p>
 * 
 * <p>Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:</p>
 * 
 * <p>The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.</p>
 * 
 * <p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.</p>
 * 
 * <p>Licensed under The MIT License</p>
 * <p>Redistributions of files must retain the above copyright notice.</p>
 * 
 * <p>Revisions<br/> 
 * 	2.0  Initial version Jan 7, 2009</p>
 *
 */

package camo.core.property
{

import flash.net.registerClassAlias;
import flash.utils.ByteArray;
import flash.utils.Proxy;
import flash.utils.flash_proxy;

dynamic public class Properties extends Proxy
	{
		protected var properties:Object = {};
		protected var propertiesIndex:Array = [];
		
		/**
		 * 
		 * @param properties
		 * @param propertiesIndex
		 * 
		 */		
		public function Properties()
		{
			registerClassAlias( "camo.core.property.Properties", Properties );
		}
		
		/**
		 * 
		 * @param name
		 * @return 
		 * 
		 */	
		override flash_proxy function deleteProperty(name:*):Boolean
		{
			var wasDeleted:Boolean = delete properties[name];
			
			if (wasDeleted) {
				
				propertiesIndex.splice(propertiesIndex.indexOf(name), 1);
				
			}

			return wasDeleted;
		}
		
		/**
		 * 
		 * @param name
		 * @return 
		 * 
		 */	
		override flash_proxy function getProperty(name:*):*
		{
			return properties[name];
		}
		
		/**
		 * 
		 * @param name
		 * @return 
		 * 
		 */	
		override flash_proxy function hasProperty(name:*):Boolean
		{
			return properties.hasOwnProperty(name);
		}
		
		/**
		 * 
		 * @param index
		 * @return 
		 * 
		 */	
		override flash_proxy function nextName(index:int):String
		{
			return propertiesIndex[index - 1];
		}
		
		/**
		 * 
		 * @param index
		 * @return 
		 * 
		 */	
		override flash_proxy function nextNameIndex(index:int):int
		{
			if (index < propertiesIndex.length)
				return index + 1;
			else
				return 0;
		}
		
		/**
		 * 
		 * @param index
		 * @return 
		 * 
		 */	
		override flash_proxy function nextValue(index:int):*
		{
			return properties[propertiesIndex[index - 1]];
		}
	
		/**
		 * 
		 * @param name
		 * @param value
		 * 
		 */
		override flash_proxy function setProperty(name:*, value:*):void
		{
			properties[name] = value;
	
			if (propertiesIndex.indexOf(name) == -1)
				propertiesIndex.push(name.toString());
			
		}

		/**
		 * 
		 * @return 
		 * 
		 */	
		public function toString():String
		{
			if(properties.styleName){
				var styleString:String = properties.styleName.concat("{");
							
				for (var prop:String in properties){
					switch (prop)
					{
						case "styleName":
								// Do nothing.
							break;
						default:
							styleString = styleString.concat(dashed(prop),":",properties[prop].toString(),";");
							break;
					}
				}
				
				styleString = styleString.concat("}");
			}
			return styleString;
			
		}
		
		/**
		 * <p>Returns an dashed-syntaxed (like-this) version of the likeThis.</p>
		 *
		 * @param string camelcaseword Camel-cased word to be "underscorized"
		 * @return string Underscore-syntaxed version of the camelcaseword
		 */
		private function dashed(camelcaseword:String):String 
		{
			var replace:String = camelcaseword.replace(/([a-z])([A-Z]{1})/g,"$1-$2").toLowerCase();
			return replace;
		}
		
		/**
		 * 
		 * @param style
		 * 
		 */		
		public function merge(style:Properties):void
		{
			for(var prop:String in style) {
				this[prop] = style[prop];
			}
		}
		
		/**
		 * 
		 * @param styleText
		 * 
		 */		
		public function parsePropertiesText(styleText:String):void
		{
			
		}
		
		/**
		 * 
		 * @return 
		 * 
		 */		
		public function clone():Properties
		{
			var myBA:ByteArray = new ByteArray();
		    myBA.writeObject(this);
		    myBA.position = 0;
		    return( Properties( myBA.readObject() ) );
		}
	}

}
